package com.sky.service.impl;

import com.sky.entity.Orders;
import com.sky.mapper.ReportMapper;
import com.sky.service.ReportService;
import com.sky.vo.OrderReportVO;
import com.sky.vo.SalesTop10ReportVO;
import com.sky.vo.TurnoverReportVO;
import com.sky.vo.UserReportVO;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.time.LocalDate;
import java.util.*;

@Service
public class ReportServiceImpl implements ReportService {
    @Autowired
    ReportMapper reportMapper;
    @Autowired
    HttpServletResponse httpServletResponse;

    @Override
    public TurnoverReportVO getOrderBytime(LocalDate begin, LocalDate end) {
        List<LocalDate> list = getDateList(begin, end);
        List<Double> doubles = new ArrayList<>();
        for (LocalDate localDate : list) {
            Double money = reportMapper.getAmount(localDate, localDate.plusDays(1), Orders.COMPLETED);
            System.out.println(localDate.toString() + "" + money);
            if (money == null) {
                doubles.add(0.0);
            } else {
                doubles.add(money);
            }
        }
        System.out.println(doubles);
        TurnoverReportVO turnoverReportVO = new TurnoverReportVO();
        turnoverReportVO.setDateList(StringUtils.join(list, ","));
        turnoverReportVO.setTurnoverList(StringUtils.join(doubles, ","));
        return turnoverReportVO;
    }

    @Override
    public UserReportVO getUserByTime(LocalDate begin, LocalDate end) {
        List<LocalDate> list = getDateList(begin, end);
        List<Integer> integers = new ArrayList<>();
        List<Integer> num = new ArrayList<>();
        for (LocalDate localDate : list) {
            Integer num1 = reportMapper.getUserInfo(localDate, localDate.plusDays(1));
            Integer num2 = reportMapper.getUserInfo(begin, localDate.plusDays(1));
            if (num1 == null) {
                integers.add(0);
            } else {
                integers.add(num1);
            }
            if (num2 == null) {
                num.add(0);
            } else {
                num.add(num2);
            }
        }
        System.out.println(num);
        System.out.println(integers);
        UserReportVO userReportVO = new UserReportVO();
        userReportVO.setNewUserList(StringUtils.join(integers, ","));
        userReportVO.setTotalUserList(StringUtils.join(num, ","));
        userReportVO.setDateList(StringUtils.join(list, ","));
        return userReportVO;
    }

    @Override
    public SalesTop10ReportVO getTop10() {
        SalesTop10ReportVO salesTop10ReportVO = new SalesTop10ReportVO();
        //select od.dish_name , count(od.num) from orders o left join in order_detaill od on  o.id = od.orders_id where o.status = 5
        LinkedList<Map> mapList = reportMapper.getTop10();
        StringBuilder stringBuilder1 = new StringBuilder();
        StringBuilder stringBuilder2 = new StringBuilder();
        System.out.println(mapList);
        for (int i = 0; i < mapList.size(); i++) { //设置10个
            if (i == 10) {
                break;
            }
            if (i == 9) {
                if (mapList.get(i) != null) {
                    stringBuilder1.append(mapList.get(i).get("name"));
                    stringBuilder2.append(mapList.get(i).get("totalNum"));
                }
            } else {
                if (mapList.get(i) != null) {
                    stringBuilder1.append(mapList.get(i).get("name") + ",");
                    stringBuilder2.append(mapList.get(i).get("totalNum") + ",");
                }
            }
        }
        System.out.println(stringBuilder1);
        System.out.println(stringBuilder2);
        salesTop10ReportVO.setNameList(stringBuilder1.toString());
        salesTop10ReportVO.setNumberList(stringBuilder2.toString());
        return salesTop10ReportVO;
    }

    @Override
    public OrderReportVO getOrderStatus(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = getDateList(begin, end);
        List<Integer> allOrdersNums = new ArrayList<>();
        List<Integer> CompleteOrderNums = new ArrayList<>();
        for (LocalDate localDate : dateList) {
            //select sum(*) orders where status=0 //[5] and ordertiem between and
            Integer allOrdersNum = reportMapper.getOrderStaus(localDate, localDate.plusDays(1), null);
            Integer CompleteOrderNum = reportMapper.getOrderStaus(localDate, localDate.plusDays(1), Orders.COMPLETED);
            allOrdersNums.add(allOrdersNum);
            CompleteOrderNums.add(CompleteOrderNum);
        }
        Integer totalNum = reportMapper.getOrderStaus(null, null, null);
        Integer orderStaus = reportMapper.getOrderStaus(null, null, Orders.COMPLETED);
        OrderReportVO reportVO = new OrderReportVO();
        reportVO.setValidOrderCountList(StringUtils.join(CompleteOrderNums, ","));
        reportVO.setOrderCountList(StringUtils.join(allOrdersNums, ","));
        reportVO.setDateList(StringUtils.join(dateList, ","));
        reportVO.setTotalOrderCount(totalNum);
        reportVO.setValidOrderCount(orderStaus);
        reportVO.setOrderCompletionRate((double) (totalNum / orderStaus));
        return reportVO;
    }

    @Override
    public void export() {
        InputStream file1 = ReportServiceImpl.class.getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
        LocalDate now = LocalDate.now();
        //报表名
        String name = "时间:" + now.toString() + "至" + now.plusDays(-30).toString();
        //总营业额
        Double amount = reportMapper.getAmount(now.plusDays(-30), now, 5);
        amount = amount == null ? 0.0 : amount;
        //订单完成率
        Integer comOrders = reportMapper.getOrderStaus(now.plusDays(-30), now, 5);
        comOrders = comOrders == null ? 0 : comOrders;

        Integer allOrders = reportMapper.getOrderStaus(now.plusDays(-30), now, null);
        allOrders = allOrders == null ? 0 : allOrders;
        Double fin = allOrders == 0 ? 0.0 :  ((double)comOrders / (double)allOrders);
        //新增用户数量
        Integer incrNum = reportMapper.getUserInfo(now.plusDays(-30), now);
        incrNum = incrNum == null ? 0 : incrNum;
        //有效订单 comOrders
        //平均客单价
        Double avg = comOrders == 0 ? 0.0 : amount / comOrders;
        try {
            XSSFWorkbook sheets = new XSSFWorkbook(file1);
            exportCell(0, 1, 1, file1, name, sheets);
            exportCell(0, 3, 2, file1, amount.toString(), sheets);
            exportCell(0, 3, 4, file1, Math.round(fin * 100.0)+"%", sheets);
            exportCell(0, 3, 6, file1, incrNum.toString(), sheets);
            exportCell(0, 4, 2, file1, comOrders.toString(), sheets);
            exportCell(0, 4, 4, file1, avg.toString(), sheets);
            //30天数据
            for (int i = 0; i < 30; i++) {
                //日期
                LocalDate localDate = now.plusDays(i - 29);
                exportCell(0, (i + 7), 1, file1, localDate.toString(), sheets);
                //营业额
                Double amount1 = reportMapper.getAmount(localDate.plusDays(-1), localDate, 5);
                amount1 = amount1 == null ? 0.0 : amount1;
                exportCell(0, (i + 7), 2, file1, amount1.toString(), sheets);
                //有效订单
                Integer dayComNum = reportMapper.getOrderStaus(localDate.plusDays(-1), localDate, 5);
                dayComNum = dayComNum == null ? 0 : dayComNum;
                exportCell(0, (i + 7), 3, file1, dayComNum.toString(), sheets);
                //完成率
                Integer dayAllNum = reportMapper.getOrderStaus(localDate.plusDays(-1), localDate, null);
                dayAllNum = dayAllNum == null ? 0 : dayAllNum;
                Double dayFin = dayAllNum == 0 ? 0.0 :  ((double)dayComNum / (double)dayAllNum);
                exportCell(0, (i + 7), 4, file1, Math.round(dayAllNum * 100.0)+"%", sheets);
                //平均客单价
                double dayAvg = dayComNum == 0 ? 0.0 : amount1 / dayComNum;
                exportCell(0, (i + 7), 5, file1, String.valueOf(dayAvg), sheets);
                //新增user
                Integer userNum = reportMapper.getUserInfo(localDate.plusDays(-1), localDate);
                userNum = userNum == null ? 0 : userNum;
                exportCell(0, (i + 7), 6, file1, userNum.toString(), sheets);
            }
            //提供下载
            ServletOutputStream outputStream = httpServletResponse.getOutputStream();
            sheets.write(outputStream);
            //释放资源
            file1.close();
            outputStream.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static void exportCell(int sheetNum, int rowNum, int lieNum, InputStream file, String value, XSSFWorkbook sheets) throws IOException {
        XSSFSheet sheetAt = sheets.getSheetAt(sheetNum);
        XSSFRow row = sheetAt.getRow(rowNum);
        XSSFCell cell = row.getCell(lieNum);
        cell.setCellValue(value);
    }

    private static List<LocalDate> getDateList(LocalDate begin, LocalDate end) {
        List<LocalDate> list = new ArrayList<>();
        list.add(begin);
        while (!begin.equals(end)) {
            begin = begin.plusDays(1);
            list.add(begin);
        }
        return list;
    }

}
